package top.suven.base.http.admin.task;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import top.suven.base.core.redis.RedisClusterServer;
import top.suven.base.http.admin.user.dao.UserJdbcDao;
import top.suven.base.http.admin.user.model.UserReport;
import top.suven.base.http.admin.user.service.UserJdbcWebService;

import java.util.*;
import java.util.concurrent.*;
import java.util.stream.Collectors;

/**
 * @ClassName:定时加载用户省份
 * @Description:
 * @Author lixiangling
 * @Date 2018/8/27 15:09
 * @Copyright: (c) 2018 gc by https://www.gc.com.cn/
 * @Version : 1.0.0
 * --------------------------------------------------------
 * modifyer    modifyTime                 comment
 *
 * --------------------------------------------------------
 */
@Component
public class UserRegionLoadTask {
    private Logger logger = LoggerFactory.getLogger(UserJdbcDao.class);
    @Autowired
    private UserJdbcWebService userJdbcWebService;
    @Autowired
    private RedisClusterServer redisClusterServer;

    private static final int MOD_NUM = 10;
    private static final String[] PROVINCE_NAMES={"北京","天津","上海","重庆","河北","山西","辽宁","吉林","黑龙江","江苏","浙江","安徽","福建","江西","山东",
            "河南","湖北","湖南","广东","海南","四川","贵州","云南","陕西","甘肃","青海","台湾","内蒙古","广西","西藏","宁夏","新疆","香港","澳门"};
    private static final List<String> PROVINCE_LIST= Arrays.asList(PROVINCE_NAMES);
    /**
     * 定时加载用户地址
     *
     */
    @Scheduled(cron="${gc.quarz.userRegion}")
    public void quarzLoadUserRegion()throws Exception{
        ExecutorService executorService = Executors.newFixedThreadPool(MOD_NUM);
        final Map<String,Integer> provinceMap = new HashMap<String,Integer>();
        final CountDownLatch runningThreadNum = new CountDownLatch(MOD_NUM);
        final LinkedBlockingQueue<Exception> exceptionQueue = new LinkedBlockingQueue<Exception>();
        List<Future> futures = new ArrayList<Future>();

        for(int i=0;i<MOD_NUM;i++) {
            final int modVal = i;
            Thread worker = new Thread() {
                @Override
                public void run() {
                    try {
                        Map<String,Integer> userProvinceMap = userJdbcWebService.getUserProvince(modVal);
                        if ( userProvinceMap==null || userProvinceMap.isEmpty()) {
                            return;
                        }
                        synchronized(this) {
                            for(Map.Entry<String,Integer> userProvince : userProvinceMap.entrySet()){
                                List<String> existsProvince  =  PROVINCE_LIST.stream().filter(e->userProvince.getKey().startsWith(e)).collect(Collectors.toList());
                                if(existsProvince == null || existsProvince.isEmpty()){
                                    continue;
                                }
                                provinceMap.put(existsProvince.get(0),provinceMap.getOrDefault(existsProvince.get(0),0)+userProvince.getValue());
                            }
                        }
                    } catch (Throwable e) {
                        logger.error("query thread[" + Thread.currentThread().getName()+ "]:",e);
                        Exception ex = new Exception(e.getMessage());
                        exceptionQueue.add(ex);
                    } finally {
                        runningThreadNum.countDown();
                    }
                }
            };
            worker.setName("UserRegion_"+modVal +"_Thread");
            futures.add(executorService.submit(worker));
        }
        runningThreadNum.await();
        if (exceptionQueue.size() != 0) {
            Exception e = exceptionQueue.poll();
            throw e;
        }
        List<UserReport> userReportList = new ArrayList<>();
        for(Map.Entry<String,Integer> userProvinceEntry : provinceMap.entrySet()){
            UserReport userReport = new UserReport();
            userReport.setName(userProvinceEntry.getKey());
            userReport.setValue(userProvinceEntry.getValue());
            userReportList.add(userReport);
        }
        if(userReportList == null ||userReportList.isEmpty()){
            logger.warn("未获取到注册区域信息");
            return;
        }
//        SerializableModel<UserReport> serializableModel = new SerializableModel();
//        serializableModel.setData(userReportList);
//        redisClusterServer.set(RedisKeys.USER_PROVINCE, SerializableUtil.toBytes(serializableModel));
    }
}
